import java.util.concurrent.*;

/**
 * <p>
 * </p>
 *
 * @author zhuolin
 * @since 2020/8/18
 */
public class TraceThreadPoolExecutor extends ThreadPoolExecutor {
    public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    public void execute(Runnable command) {
        super.execute(wrap(command, clientException(), Thread.currentThread().getName()));
    }

    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(wrap(task, clientException(), Thread.currentThread().getName()));
    }

    private Exception clientException() {
        return new Exception("client run trace");
    }

    private Runnable wrap(Runnable task, Exception clientException, String clientThreadName) {
        return () -> {
            try {
                task.run();
            } catch (Exception e) {
                clientException.printStackTrace();
                throw e;
            }
        };
    }

    public static void main(String[] args) {
        TraceThreadPoolExecutor traceThreadPoolExecutor = new TraceThreadPoolExecutor(0, Integer.MAX_VALUE, 0L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

        for (int i = 0; i < 10; i++) {
            traceThreadPoolExecutor.execute(new ThreadPoolTrace.DivTask(100, i));
        }
    }
}
